/*
    File:       HttpMagazineController.m

    Contains:   Manages the List tab.

    Written by: Sunny

    Copyright:  Copyright (c) 2010 SUNNY Inc. All Rights Reserved.

    

*/

#import "HttpMagazineController.h"

#import "HttpDelegate.h"

#include <sys/socket.h>
#include <sys/dirent.h>

#include <CFNetwork/CFNetwork.h>

#import "ParseMagazineOperation.h"

#import "WZ66WZZBAppDelegate.h"

#import "MainViewController.h"

#pragma mark * HttpController

@interface HttpMagazineController ()

// Properties that don't need to be seen by the outside world.

@property (nonatomic, readonly) BOOL              isReceiving;
@property (nonatomic, retain)   NSInputStream *networkStream;
@property (nonatomic, retain)   NSMutableData *listData;
@property (nonatomic, retain)   NSMutableArray *listEntries;
@property (nonatomic, retain)   NSURLConnection *connection;

@property (nonatomic, retain)   HttpDelegate *httpUtil;

- (void)_updateStatus:(NSString *)statusString;

@end

@implementation HttpMagazineController

+ (void)initialize
// Set up our default preferences.  We can't do this in -applicationDidFinishLaunching: 
// because it's too late; the view controller's -viewDidLoad method has already run 
// by the time applicationDidFinishLaunching: is called.
{
	//TODO
}

- (id) init
{
	if (self = [super init]) {
		self.listXml = [[[NSMutableArray alloc] init] autorelease];
	}
	
    return (self);
	
}

@synthesize networkStream   = _networkStream;
@synthesize listData        = _listData;
@synthesize listEntries     = _listEntries;
@synthesize status          = _status;
@synthesize httpUtil         = _httpUtil;
@synthesize listXml = _listXml;
@synthesize folderBaseUrl = _folderBaseUrl;
@synthesize connection;

@synthesize parseQueue;

// the main function for this NSOperation, to start the parsing
//
- (void)main {
	//TODO
	//NSLog(@"HttpMagazineController Main");
	
}

#pragma mark * Status management

// These methods are used by the core transfer code to update the UI.
//
- (void)_receiveDidStart
{
	//Init PareQueue
	parseQueue = [NSOperationQueue new];
	
	//TODELETE 
	//[self.listEntries removeAllObjects];
    
	//Start NetWorking
	[self.httpUtil didStartNetworking];
}

- (void)_updateStatus:(NSString *)statusString
{
    assert(statusString != nil);
    self.status = statusString;
}

- (void)_addListEntries:(NSArray *)newEntries
{
    assert(self.listEntries != nil);
    [self.listEntries addObjectsFromArray:newEntries];
}

- (void)_receiveDidStopWithStatus:(NSString *)statusString
{
    if (statusString == nil) {
        statusString = @"List succeeded";
    }
    [self _updateStatus:statusString];
	//Stop NetWorking
    [self.httpUtil didStopNetworking];
}

#pragma mark * Core transfer code

// This is the code that actually does the networking.
//
- (BOOL)isReceiving
{
    return (self.networkStream != nil);
}

- (void)_startReceive:(NSString*) urlText
    // Starts a connection to download the current URL.
{
    BOOL                success;
    NSURL *             url;
    NSURLRequest *      request;
    
    assert(self.networkStream == nil);      // don't tap receive twice in a row!

	// Init Some Array & Util
	self.listEntries = [[[NSMutableArray alloc] init] autorelease];
    self.httpUtil = [[[HttpDelegate alloc] init] autorelease];
	self.status = @"";
	
    // First get and check the URL.
	url = [self.httpUtil smartURLForString:urlText];
    success = (url != nil);
	
    // If the URL is bogus, let the user know.  Otherwise kick off the connection.
    if (!success) {
        [self _updateStatus:@"Invalid URL"];
    } else {
        // Open a connection for the URL.
        request = [NSURLRequest requestWithURL:url];
        assert(request != nil);
        
        self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
        assert(self.connection != nil);
        
        [self _receiveDidStart];
    }
}

- (void)_stopReceiveWithStatus:(NSString *)statusString
    // Shuts down the connection and displays the result (statusString == nil) 
    // or the error status (otherwise).
{
	if (self.connection != nil) {
        [self.connection cancel];
        self.connection = nil;
    }
    [self _receiveDidStopWithStatus:statusString];
    self.listData = nil;
}

#pragma mark -
#pragma mark NSURLConnection delegate methods

//Sent when the connection has received sufficient data 
//To construct the URL response for its request.
//
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    // check for HTTP status code for proxy authentication failures
    // anything in the 200 to 299 range is considered successful,
    // also make sure the MIMEType is correct:
    //
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
	NSLog(@"Connection Test HttpResponse statusCode: %d \n HttpResponse MIMEType: %@"
		  ,[httpResponse statusCode], [response MIMEType]);
	
    if ((([httpResponse statusCode]/100) == 2) && [[response MIMEType] isEqual:@"text/xml"]) {
        self.listData = [NSMutableData data];
    } else {
        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:
                                  NSLocalizedString(@"HTTP Error",
                                                    @"Error message displayed when receving a connection error.")
                                                             forKey:NSLocalizedDescriptionKey];
        NSError *error = [NSError errorWithDomain:@"HTTP" code:[httpResponse statusCode] userInfo:userInfo];
        [[WZ66WZZBAppDelegate sharedAppDelegate].mainViewController handleError:error];
    }
}

//Sent as a connection loads data incrementally.
//
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.listData appendData:data];
}

//Sent when a connection fails to load its request successfully.
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;   
    if ([error code] == kCFURLErrorNotConnectedToInternet) {
        // if we can identify the error, we can present a more precise message to the user.
        NSDictionary *userInfo =
        [NSDictionary dictionaryWithObject:
         NSLocalizedString(@"No Connection Error",
                           @"Error message displayed when not connected to the Internet.")
                                    forKey:NSLocalizedDescriptionKey];
        NSError *noConnectionError = [NSError errorWithDomain:NSCocoaErrorDomain
                                                         code:kCFURLErrorNotConnectedToInternet
                                                     userInfo:userInfo];
        [[WZ66WZZBAppDelegate sharedAppDelegate].mainViewController handleError:noConnectionError];
    } else {
        // otherwise handle the error generically
        [[WZ66WZZBAppDelegate sharedAppDelegate].mainViewController handleError:error];
    }
    self.connection = nil;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    self.connection = nil;
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;   
    
    // Spawn an NSOperation to parse the news data so that the UI is not blocked while the
    // application parses the XML data.
    //
    // IMPORTANT! - Don't access or affect UIKit objects on secondary threads.
    //
	//NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
	//NSMutableString *aStr = [[NSMutableString alloc] initWithData:self.listData encoding:NSUTF8StringEncoding];
	//NSLog(@"MagazinesXMLConent:\n%@", aStr);
	
    ParseMagazineOperation *parseMagazineOperation = [[ParseMagazineOperation alloc] initWithData:self.listData ];
    [self.parseQueue addOperation:parseMagazineOperation];
    [parseMagazineOperation release];   // once added to the NSOperationQueue it's retained, we don't need it anymore
    
    // newsData will be retained by the NSOperation until it has finished executing,
    // so we no longer need a reference to it in the main thread.
    self.listData = nil;
}

// Dealloc
//
- (void)dealloc
{
    [self _stopReceiveWithStatus:@"Stopped"];
	
    //TODO
	[_networkStream release];
	[_listData release];
	[_listEntries release];
	[_status release];
	[_httpUtil release];
	[_listXml release];
	[_folderBaseUrl release];
	[parseQueue release];
	[connection release];
	
    [super dealloc];
}

@end
